#include "stdafx.h"
#include "parser.h"
#include "jsoncpp\writer.h"
#include "jsoncpp\reader.h"


void appendRow(Json::Value &arrayValue, const SqlResponse::Row & row)
{
	SqlResponse::Row::const_iterator it;
	for (it = row.begin(); it != row.end(); ++it)
	{
		arrayValue.append( Json::Value( parser::unicode_to_utf8(it->c_str()) ) );
	}
}

void appendRows(Json::Value &arrayValue, const SqlResponse::Rows & rows)
{
	SqlResponse::Rows::const_iterator it;
	for (it = rows.begin(); it != rows.end(); ++it)
	{
		Json::Value row(Json::arrayValue);
		appendRow(row, *it);
		arrayValue.append(row);
	}
}

void saveTable(Json::Value &root, const SqlResponse::Table & table)
{
	Json::Value header(Json::arrayValue);
	appendRow(header, table.header);
	root["table"]["header"] = header;

	Json::Value rows(Json::arrayValue);
	appendRows(rows, table.rows);
	root["table"]["rows"] = rows;
}

const wchar_t * parser::utf8_to_unicode(const char *ut8text)
{
	assert(ut8text);

	static wchar_t *buffer = 0;
	static int bufferLength = 0;

	int needLength = ::MultiByteToWideChar(CP_UTF8, 0, ut8text, -1, 0, 0);

	if (needLength > bufferLength && buffer)
	{
		delete [] buffer;
		buffer = 0;
		bufferLength = 0;
	}

	if (!buffer)
	{
		buffer = new wchar_t[needLength+16];
		if (buffer)
			bufferLength = needLength+16;
	}

	if ( buffer && ::MultiByteToWideChar(CP_UTF8, 0, ut8text, -1, buffer, bufferLength) )
	{
		return buffer;
	}

	return L"";
}

const char * parser::unicode_to_utf8(const wchar_t *unicodetext)
{
	assert(unicodetext);

	static const char BAD_CHAR = '?';
	static char *buffer = 0;
	static int bufferLength = 0;

	int needLength = ::WideCharToMultiByte(CP_UTF8, 0, unicodetext, -1, 0, 0, &BAD_CHAR, 0);

	if (needLength > bufferLength && buffer)
	{
		delete [] buffer;
		buffer = 0;
		bufferLength = 0;
	}

	if (!buffer)
	{
		buffer = new char[needLength+16];
		if (buffer)
			bufferLength = needLength+16;
	}

	if ( buffer && ::WideCharToMultiByte(CP_UTF8, 0, unicodetext, -1, buffer, bufferLength, &BAD_CHAR, 0) )
	{
		return buffer;
	}

	return "";
}

bool parser::text2request(const std::string &jsonText, SqlRequest &request)
{
	Json::Value root;
	Json::Reader reader;
	if ( reader.parse(jsonText, root) )
	{
		request.groupId = utf8_to_unicode( root["groupid"].asString().c_str() );
		request.requestId = utf8_to_unicode( root["requestid"].asString().c_str() );
		request.request = utf8_to_unicode( root["request"].asString().c_str() );

		return true;
	}

	return false;
}

void parser::response2text(const SqlResponse &response, std::string &text)
{
	Json::Value root;
	root["requestid"] = unicode_to_utf8( response.requestId.c_str() );
	root["errorcode"] = unicode_to_utf8( response.errorCode.c_str() );
	saveTable(root, response.responseTable);

	text = root.asString();
}
